package org.enlongWu.controller;

import jakarta.annotation.Resource;
import jakarta.validation.constraints.Pattern;
import org.enlongWu.pojo.*;
import org.enlongWu.service.MessageService;
import org.enlongWu.service.RoleService;
import org.enlongWu.service.UserService;
import org.enlongWu.utils.JwtUtil;
import org.enlongWu.utils.Md5Util;
import org.enlongWu.utils.ThreadLocalUtil;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
    @Autowired//注入bean
    private UserService userService;
    @Autowired//注入bean
    private MessageService messageService;
    @Autowired
    private RoleService roleService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/getById")
    public Result getUserById(@RequestParam Integer id){
        System.out.println(id);
//        Integer userid =  Integer.parseInt(id);
        User user = userService.findByUserid(id);
        System.out.println(user);
        return Result.success(user,"获取用户信息成功");
    }

    /**
     * 通过用户名获取roleName
     * @param username
     * @return 对应的权限中文名
     */
    @GetMapping("/getRoleByUsername")
    public Result getRole(@RequestParam String username){
        System.out.println("想获取"+username);
//        Integer userid =  Integer.parseInt(id);
        User user = userService.findByUserName(username);
        Role role = roleService.findByRoleStr(user.getRole());//通过role字符串获取roleName
        System.out.println(role);
        return Result.success(role,"获取用户权限名成功");
    }

    @PostMapping("/register")   //请求路径为      虚拟路径 + /user/register
    public Result register(@Pattern(regexp = "^\\S{5,16}$") String username,@Pattern(regexp = "^\\S{5,16}$") String password,String role,String nickname,String email,String userPic){
        System.out.println(nickname+email+userPic);
        //查重
        User u = userService.findByUserName(username);
        if (u == null){
            //格式校验
            if (username.toString().length() < 5 || username.toString().length() > 16){
                return Result.error("用户名应由5至16位字符组成");
            }else if (password.toString().length() < 5 || password.toString().length() > 16){
                return Result.error("密码应由5至16位字符组成");
            }
            //注册
            userService.register(username,password,nickname,email,userPic,role);
            return Result.success("用户"+username+"注册成功");
        }else {
            return Result.error("用户名已被占用！");
        }

    }

    @PostMapping("/login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {

        //根据用户名查询用户
        User loginUser = userService.findByUserName(username);
        //判断该用户是否存在
        if (loginUser == null) {
            return Result.error("用户名不存在");
        }
        //判断密码是否正确  loginUser对象中的password是密文
        if (Md5Util.getMD5String(password).equals(loginUser.getPassword())) {
            if (loginUser.getRole().equals("freeze")){
                return Result.error("账户被冻结，请联系管理员");
            }else {
                //登录成功
                Map<String, Object> claims = new HashMap<>();
                claims.put("id", loginUser.getId());
                claims.put("username", loginUser.getUsername());
                String token = JwtUtil.genToken(claims);
                //把token存储到redis中
                ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
                operations.set(token,token,1, TimeUnit.HOURS);//token既是键又是值，一小时过期
                return Result.success(token,"["+username+"]登录成功");
            }
        }
        return Result.error("密码错误");
    }

    /**
     * 拦截器存放的线程局部变量token -> 用户信息
     * @return
     */
    @GetMapping("/userInfo")
    public Result<User> userInfo(/*@RequestHeader(name="Authorization") String token*/){
/*        //别再重新取了，拦截时就获取过了，见下
        Map<String, Object> map = JwtUtil.parseToken(token);//解析token信息
*/
        Map<String, Object> map = ThreadLocalUtil.get();//复用拦截器（LoginInterceptor）取出的token信息
        String username = (String) map.get("username");//取出用户名
        User user = userService.findByUserName(username);//根据用户名查询用户信息
        return Result.success(user);
    }

    /**
     * 更改用户信息，当改了权限，发送消息
     * @param user
     * @return
     */
    @PutMapping("/update")
     public Result update(@RequestBody @Validated User user){
        //获取出操作者信息
        Map<String, Object> map = ThreadLocalUtil.get();//复用拦截器（LoginInterceptor）取出的token信息
        String username = (String) map.get("username");
        User sendUser = userService.findByUserName(username);

        //被操作者的旧信息
        User oldUserInfo = userService.findByUserName(user.getUsername());
        //获取role的中文名称以便打印和发送消息
        Role oldRole = roleService.findByRoleStr(oldUserInfo.getRole());
        Role newRole = roleService.findByRoleStr(user.getRole());
        if (!oldUserInfo.getRole().equals(user.getRole())){//权限修改，发送消息通知
            Message message = new Message();
            message.setTitle("权限修改");
            message.setContent("你的权限被从【"+oldRole.getRoleName()+"】改成【"+newRole.getRoleName()+"】");
            message.setSendUser(sendUser.getId());
            message.setReceiveUser(user.getId());
            message.setState("未读");
            message.setMessageType(2);//类型：通知
            messageService.add(message);//发送消息
        }

        userService.update(user);
        return Result.success("更改成功");
    }

    /**
     * 更新用户头像
     * @param avatarUrl
     * @return
     */
    @PatchMapping("/updateAvatar")
    public Result updateAvatar(@RequestParam /*@URL*/ String avatarUrl) {
        userService.updateAvatar(avatarUrl);
        return Result.success();
    }


    /**
     * 更新用户密码，系统管理员改的
     * @param params 来自请求参数，包含用户id，邮箱，新密码，确认密码
     * @return
     */
    @PatchMapping("/admin/updatePwd")
    public Result updatePwd(@RequestBody Map<String, String> params) {
        //1.校验参数
        String newPwd = params.get("newPwd");
        String idStr = params.get("id");//用户id
        if (!StringUtils.hasLength(newPwd) || !StringUtils.hasLength(idStr)) {
            return Result.error("缺少必要的参数");
        }
        // 将字符串 id 转换为 Integer
        Integer id = null;
        try {
            id = Integer.valueOf(idStr);
        } catch (NumberFormatException e) {
            // 如果转换失败，返回错误信息
            return Result.error("无效的用户ID");
        }


//        String email = params.get("email");//邮箱.......忘记密码才要邮箱验证，删
        //邮箱验证。。。。。。。。。。。。。。删


        //2.调用service完成密码更新
        userService.updatePwd(newPwd,id);
        return Result.success("密码修改成功");

    }

    /**
     * 更改密码（自己的账号）
     * @param params 来自请求参数，包含 旧密码，新密码，确认密码
     * @param token 登录时携带的token，包含用户信息
     * @return
     */
    @PatchMapping("/updatePwd")
    public Result resectPwd(@RequestBody Map<String, String> params,@RequestHeader("Authorization") String token) {
        //1.校验参数
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error("缺少必要的参数");
        }

        //原密码是否正确
        //调用userService根据用户名拿到原密码,再和old_pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser = userService.findByUserName(username);
        if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密码填写不正确");
        }

        //newPwd和rePwd是否一样
        if (!rePwd.equals(newPwd)){
            return Result.error("两次填写的新密码不一样");
        }

        //2.调用service完成密码更新
        userService.updatePwd(newPwd);
        //删除redis中对应的token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return Result.success();
    }


    /**
     * 查询用户列表
     * @param role 权限字符串
     *             包括admin系统管理员，engineer工程师，customer顾客 冷库拥有者，initial为新注册用户
     * @return  标准返回结果Result.data
     */
    @GetMapping("/list")
    public Result<PageBean<User>> userList(Integer pageNum,
                                              Integer pageSize,
                                           @RequestParam(required = false) String searchString,
                                              @RequestParam(required = false) String role) {
        System.out.println("-----------------"+pageNum+pageSize+searchString);
        PageBean<User> pb =  userService.list(pageNum,pageSize,searchString,role);

        return Result.success(pb,"查询用户列表成功");
    }

//    /**
//     * 删除用户
//     * @param id 用户id
//     * @return 标准返回结果Result.data
//     */
//    @DeleteMapping("/delete")
//    public Result delete(@RequestParam Integer id) {
//        userService.userList(role);
//        return Result.success();
//    }


}
